package goconfig

import (
	"fmt"
	"os"
	"os/exec"
	"strconv"
	"sync"
	"syscall"

	"gitee.com/lorock/goconfig/abaolog"
	"gitee.com/lorock/goconfig/redispool"
	"github.com/fsnotify/fsnotify"
	"github.com/go-redis/redis"
	"github.com/sirupsen/logrus"

	"github.com/spf13/viper"
)

var configDir = "/config/"

// Rdb redis 客户端类型
var Rdb *redis.Client

// viperConfig 全局配置变量
var viperConfig *viper.Viper
var m sync.Mutex

// Init 初始化配置
func init() {
	// appName 应用名称
	// appName := "ABaoConfig"
	// // envPrefixName 需要使用系统环境变量时，可以设置前缀
	// envPrefixName := "aclb"
	//获取项目的执行路径
	currentPath, err := os.Getwd()
	if err != nil {
		logrus.Errorln(err)
	}
	v := viper.New()
	// v.SetEnvPrefix(envPrefixName)
	v.AutomaticEnv()
	// os.Setenv("APP_NAME", appName)
	v.AddConfigPath(currentPath + configDir) //设置读取的文件路径
	v.SetConfigName("app")                   //设置读取的文件名
	v.SetConfigType("env")                   //设置文件的类型
	ReadConfig(v)                            // 根据以上配置读取加载配置文件
	v.WatchConfig()                          //监视配置
	v.OnConfigChange(func(e fsnotify.Event) {
		pid := syscall.Getpid()
		logrus.Println("Config file changed:", e.Name)
		cmd := exec.Command("kill", "-1", strconv.Itoa(pid))
		out, err := cmd.CombinedOutput()
		if err != nil {
			logrus.Fatalf("config reload failed with %s\n", err)
		}
		logrus.Printf("config reload out:\n%s\n", string(out))
	})
	viperConfig = v
}

// Init 系统初始化配置
func Init() {

	// 打印软件版本信息
	fmt.Println(GetString("APP_NAME"), GetString("APP_VERSION"))
	fmt.Println(GetString("APP_HELP"))
	// fmt.Println(GetInt("APP_SERVER_PORT"))

	// 日志是否写入本地文件
	logToFile := GetBool(`APP_LOG_LOGTOFILE`)
	fmt.Println("Log To File :", logToFile)
	logrus.Debugln("Log To File :", logToFile)
	// 获取日志写入文件配置
	// 日志路径
	logFilePath := GetString(`APP_LOG_FILEPATH`)
	// 日志文件名称
	logFileName := GetString(`APP_LOG_FILENAME`)
	// 日志文件保留多少天
	logFileDays := GetInt(`APP_LOG_FILEDAYS`)
	// 日志级别  0：PanicLevel 	1：FatalLevel 	2：ErrorLevel  3：WarnLevel  4：InfoLevel  5：DebugLevel  6：TraceLevel
	logLevel := GetUint32(`APP_LOG_LEVEL`)
	// 显示函数调用文件名以及行号
	lineNumber := GetBool(`APP_LOG_LINE_NUMBER`)
	// 获取日志写入ES配置
	esURL := GetStringSlice(`APP_ES_URL`)
	// 日志产生服务器名称
	esHost, _ := os.Hostname()
	esLogIndex := GetString(`APP_ES_LOG_INDEX`)
	esUserName := GetString(`APP_ES_USER_NAME`)
	esUserPassword := GetString(`APP_ES_USER_PASSWORD`)
	// 日志是否写入ES
	logToEs := GetBool(`APP_LOG_LOGTOES`)
	fmt.Println("Log To ES :", logToEs)
	fmt.Println("Log To ES Url :", esURL)
	logrus.Debugln("Log To ES :", logToEs)

	// redis实例初始化
	redisEnable := GetBool(`APP_REDIS`)
	// 获取redis相关配置
	redisIP := GetString(`APP_REDIS_SERVER_IP`)
	redisPort := GetString(`APP_REDIS_SERVER_PORT`)
	redisPassword := GetString(`APP_REDIS_PASSWORD`)
	redisDB := GetInt(`APP_REDIS_DB`)

	// 设置是否启用Redis
	if redisEnable {
		Rdb = redispool.NewRedisPool(redisIP, redisPort, redisPassword, redisDB)
	}

	// 设置日志级别为warn以上
	logrus.SetLevel(logrus.Level(logLevel))
	// 日志写入文件判断
	if logToFile {
		go abaolog.File(logFilePath, logFileName, "text", logFileDays, lineNumber)
	}

	// 日志写入ES判断
	if logToEs {
		go abaolog.Es(esURL, esHost, esLogIndex, esUserName, esUserPassword, logLevel)
	}

}
